<?php
/*
 * 加载其它类的类
 */
class Loader{
	/**
	 * List of loaded base classes
	 * Set by the controller class
	 *
	 * @var array
	 * @access protected
	 */
	protected $_base_classes		= array(); // Set by the controller class	
	/**
	 * List of loaded files
	 *
	 * @var array
	 * @access protected
	 */
	protected $_ci_loaded_files		= array();	
	/**
	 * 构造函数
	 *
	 * 设置默认变量
	 */
	public function __construct()
	{
		$this->_ci_ob_level  = ob_get_level();
		$this->_ci_library_paths = array(APPPATH, FPATH);
		$this->_ci_helper_paths = array(APPPATH, FPATH);
		$this->_ci_model_paths = array(APPPATH);
		$this->_ci_view_paths = array(APPPATH.'views/'	=> TRUE);
	//	log_message('debug', "Loader Class Initialized");
	
	}
	// --------------------------------------------------------------------
	
	/**
	 * 初始化自动加载的类
	 * @param 	array
	 * @return 	object
	 */
	public function initialize()
	{
		$this->_ci_classes = array();
		$this->_ci_loaded_files = array();
		$this->_ci_models = array();
		$this->_base_classes =& is_loaded();
	
	//	$this->_ci_autoloader();
	
		return $this;
	}	
	// --------------------------------------------------------------------
	
	/**
	 * 加载类
	 */
	public function library($library = '', $params = NULL, $object_name = NULL)
	{
		if (is_array($library))
		{
			foreach ($library as $class)
			{
				$this->library($class, $params);
			}
	
			return;
		}
	
		if ($library == '' OR isset($this->_base_classes[$library]))
		{
			return FALSE;
		}
	
		if ( ! is_null($params) && ! is_array($params))
		{
			$params = NULL;
		}
	
		$this->_load_class($library, $params, $object_name);
	}
	// --------------------------------------------------------------------
	
	/**
	 * Load class
	 *
	 * This function loads the requested class.
	 *
	 * @param	string	the item that is being loaded
	 * @param	mixed	any additional parameters
	 * @param	string	an optional object name
	 * @return	void
	 */
	protected function _load_class($class, $params = NULL, $object_name = NULL)
	{
		// Get the class name, and while we're at it trim any slashes.
		// The directory path can be included as part of the class name,
		// but we don't want a leading slash
		$class = str_replace('.php', '', trim($class, '/'));
	
		// Was the path included with the class name?
		// We look for a slash to determine this
		$subdir = '';
		if (($last_slash = strrpos($class, '/')) !== FALSE)
		{
			// Extract the path
			$subdir = substr($class, 0, $last_slash + 1);
			// Get the filename from the path
			$class = substr($class, $last_slash + 1);
		}
		$subclass = APPPATH.'libraries/'.$subdir.$class.'.php';
		$baseclass = FPATH.'libraries/'.config_item('subclass_prefix').ucfirst($class).'.php';
		if (!in_array($class, $this->_ci_classes) || (! is_null($object_name) && ! isset($CI->$object_name))){
			if(file_exists($baseclass)){
				include_once($baseclass);
				return $this->_init_class($class, '', $params, $object_name);
			}
			if(file_exists($subclass)){
				include_once($subclass);
				return $this->_init_class($class, config_item('subclass_prefix'), $params, $object_name);
			}
			$this->_ci_classes[]=$class;
			
		}else{
			$is_duplicate = TRUE;
			log_message('debug', $class." class already loaded. Second attempt ignored.");
			return;			
		}		
		// One last attempt.  Maybe the library is in a subdirectory, but it wasn't specified?
		if ($subdir == '')
		{
			$path = strtolower($class).'/'.$class;
			return $this->_load_class($path, $params);
		}
	
		// If we got this far we were unable to find the requested class.
		// We do not issue errors if the load call failed due to a duplicate request
		if ($is_duplicate == FALSE)
		{
			log_message('error', "Unable to load the requested class: ".$class);
		//	show_error("Unable to load the requested class: ".$class);
		}
	}
	
	// --------------------------------------------------------------------
	
	/**
	 * Instantiates a class
	 *
	 * @param	string
	 * @param	string
	 * @param	bool
	 * @param	string	an optional object name
	 * @return	null
	 */
	protected function _init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
	{
		// Is there an associated config file for this class?  Note: these should always be lowercase
		
		if ($prefix == '')
		{
			if (class_exists('CI_'.$class))
			{
				$name = 'CI_'.$class;
			}
			elseif (class_exists(config_item('subclass_prefix').$class))
			{
				$name = config_item('subclass_prefix').$class;
			}
			else
			{
				$name = $class;
			}
		}
		else
		{
			$name = $prefix.$class;
		}
	
		// Is the class name valid?
		if ( ! class_exists($name))
		{
			log_message('error', "Non-existent class: ".$name);
		//	show_error("Non-existent class: ".$class);
		}
	
		// Set the variable name we will assign the class to
		// Was a custom class name supplied?  If so we'll use it
		$class = strtolower($class);
	
		if (is_null($object_name))
		{
			$classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
		}
		else
		{
			$classvar = $object_name;
		}
	
		// Save the class name and object name
		$this->_ci_classes[$class] = $classvar;
	
		// Instantiate the class
		$LK =& get_instance();
		if ($config !== NULL)
		{
			$LK->$classvar = new $name($config);
		}
		else
		{
			$LK->$classvar = new $name;
		}
	}
	
}